package com.wei;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;

import com.wei.io.MapConfigLoader;
import com.wei.io.SaveRecord;
import com.wei.model.MapConfig;
import com.wei.model.TileCoord;

import lombok.extern.log4j.Log4j;

@Log4j
public class TaskThread extends Thread{

	private BaiduSourceProvider tmsSourceProvider;
	private final String imageStragePath ;
	private final Integer indexStrageCycle;
	private final SaveRecord saveRecord = new SaveRecord();
	private final Long startTime = System.currentTimeMillis();
	private final Double totalTile ;
	
	public TaskThread(BaiduSourceProvider tmsSourceProvider, String threadName, MapConfig mapConfig) {
		super(threadName);
		this.tmsSourceProvider = tmsSourceProvider;
		this.imageStragePath = mapConfig.getImageStragePath();
		this.indexStrageCycle = mapConfig.getIndexStrageCycle();
		this.totalTile = tmsSourceProvider.getTmsTileGrid().getTotalTile();
	}
	
	public void run() {
		while (true) {
			try {
				TileCoord tileCoord = tmsSourceProvider.getNextTileCoord();
				if(tileCoord == null) {
					log.info("未获取到下一个瓦片下载对象，退出任务下载线程。花费总时间:"+(System.currentTimeMillis()-startTime)+"ms");
					break;
				}
				this.dowloadImage(tileCoord);
				int curIndex = tileCoord.getIndex();
				this.saveDowloadRecord(curIndex);
			} catch (Exception e) {
				log.error("出现未知异常!", e);
			}
		}
	}
	
	public static void main(String[] args) {
		
		String url = "http://online6.map.bdimg.com/onlinelabel/?qt=tile&styles=pl&udt=20171026&scaler=1&p=1&qt=tile&x=M1359&y=M7141&z=15";
		TileCoord coord = new TileCoord(0, 15, -1359, -7141);
		MapConfig config = MapConfigLoader.getInstance().getMapConfig();
		TaskThread t = new TaskThread(new BaiduSourceProvider(config), "", config);
		t.dowloadImage(coord);;
		
	}

	public synchronized void dowloadImage(TileCoord tileCoord) {
		String imageUrl = tmsSourceProvider.getRequestUrl(tileCoord);
		String path = this.getImageStragePath(tileCoord);
		try {
			URL url = new URL(imageUrl);
			File file = new File(path);
			URLConnection urlConn = url.openConnection();
			urlConn.setConnectTimeout(1000 * 5);
			urlConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
			urlConn.setRequestProperty("Accept-Language", "zh-CN,en,*");
			urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
			DataInputStream in = new DataInputStream(urlConn.getInputStream());
			DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
			in.close();
			out.close();
		}catch(ConnectException | SocketTimeoutException e) { 
			log.fatal("wait 100ms,imageUrl:"+imageUrl+", errMsg:"+e.getMessage());
			log.error(e.getMessage(), e);
			try {
				this.wait(100);
			} catch (InterruptedException e1) {
				log.error(e1.getMessage(), e);
			}
		}catch (IOException e) {
			log.fatal("imageUrl:"+imageUrl+", errMsg:"+e.getMessage());
			log.error(e.getMessage(), e);
		}
	}
	
	private void saveDowloadRecord(int curIndex) {
		if(curIndex % this.indexStrageCycle == 0) {
			saveRecord.save(curIndex, tmsSourceProvider.getCurZoom());
			double b = curIndex/totalTile;
			log.info("当前瓦片下载完成比:"+b);
		}
	}
	
	private String getImageStragePath(TileCoord tileCoord) {
		String x = tileCoord.getX() < 0 ? "M"+Math.abs(tileCoord.getX()) : tileCoord.getX()+"";
		String y = tileCoord.getY() < 0 ? "M"+Math.abs(tileCoord.getY()) : tileCoord.getY()+"";
		x = x.substring(0, x.indexOf("."));
		y = y.substring(0, y.indexOf("."));
		String url = imageStragePath;
		url = url.replace("{z}", tileCoord.getZoom() + "");
		url = url.replace("{x}", x);
		this.createPath(url);
		return url + File.separatorChar + y +".png";
	}
	
	private void createPath(String path) {
		File file = new File(path);
		if(!file.exists()) {
			file.mkdirs();
		}
	}
	
}
